#include "journal.h"

#include "place.h"
#include "wfnet.h"

#include <QtCore/QPair>

using namespace core;
using namespace net;
using namespace wfnet;

typedef QPair<uint, nid> CombinedKey;

Journal::Journal(WfNet* parent) :
    m_parent(parent),
    m_steps(0),
    m_tokens(),
    m_executions()
{

}

int Journal::steps() const
{
    return m_steps;
}

TypeValue Journal::tokens(const nid& place) const
{
    TypeValue ret = "";

    if (m_tokens.contains(place))
    {
        ret = m_tokens[place];
    }

    return ret;
}

int Journal::executions(const nid& transition) const
{
    int ret = -1;

    if (m_executions.contains(transition))
    {
        ret = m_executions[transition];
    }

    return ret;
}

void Journal::incrementSteps()
{
    ++m_steps;
}

void Journal::transitionExecuted(const nid& transition)
{
    if (m_executions.contains(transition))
    {
        ++m_executions[transition];
    }
    else
    {
        m_executions[transition] = 1;
    }
}

void Journal::finishJournal()
{
    m_tokens.clear();

    foreach (Place* place, m_parent->m_places)
    {
        m_tokens[place->getId()] = place->getTokens()->toValue();
    }
}

BatchJournal::BatchJournal(WfNet* parent) :
    m_parent(parent),
    m_runs(0),
    m_steps(),
    m_tokens(),
    m_executions()
{

}

uint BatchJournal::runs() const
{
    return m_runs;
}

int BatchJournal::steps(uint run) const
{
    int ret = -1;

    if (m_steps.contains(run))
    {
        ret = m_steps[run];
    }

    return ret;
}

TypeValue BatchJournal::tokens(uint run, const nid& place) const
{
    TypeValue ret = "";

    CombinedKey key(run, place);

    if (m_tokens.contains(key))
    {
        ret = m_tokens[key];
    }

    return ret;
}

int BatchJournal::executions(uint run, const nid& transition) const
{
    int ret = -1;

    CombinedKey key(run, transition);

    if (m_executions.contains(key))
    {
        ret = m_executions[key];
    }

    return ret;
}

int BatchJournal::executions(const nid &transition) const
{
    int ret = -1;

    for (uint i = 0; i < m_runs; ++i)
    {
        CombinedKey key(i, transition);

        if (m_executions.contains(key))
        {
            ret += m_executions[key];
        }
    }

    return ret;
}

void BatchJournal::beginNewRun()
{
    ++m_runs;
}

void BatchJournal::incrementSteps()
{
    if (m_steps.contains(m_runs))
    {
        ++m_steps[m_runs];
    }
    else
    {
        m_steps[m_runs] = 1;
    }
}

void BatchJournal::transitionExecuted(const nid& transition)
{
    CombinedKey key(m_runs, transition);

    if (m_executions.contains(key))
    {
        ++m_executions[key];
    }
    else
    {
        m_executions[key] = 1;
    }
}

void BatchJournal::finishJournal()
{
    foreach (Place* place, m_parent->m_places)
    {
        CombinedKey key(m_runs, place->getId());

        m_tokens[key] = place->getTokens()->toValue();
    }
}
